package light.head.controller.sys;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import light.head.cache.Cache;
import light.head.config.ConfigParm;
import light.head.constant.Msg;
import light.head.constant.Parm;
import light.head.constant.Sys;
import light.head.constant.Url;
import light.head.dao.sys.FileDAO;
import light.head.dao.sys.OrganDAO;
import light.head.dao.sys.PostDAO;
import light.head.dao.sys.RoleDAO;
import light.head.dao.sys.UserInfoDAO;
import light.head.enm.RESULT;
import light.head.framework.base.SupporterController;
import light.head.framework.entity.PageBean;
import light.head.framework.utils.DownLoadUtils;
import light.head.framework.utils.MD5Utils;
import light.head.framework.utils.PinYinUtils;
import light.head.model.FileInfo;
import light.head.model.Organ;
import light.head.model.Post;
import light.head.model.Role;
import light.head.model.UserAnnex;
import light.head.model.UserInfo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import com.google.gson.Gson;

/**
 * 各机构管理自己的用户时使用
 * @author Jian
 */
@Controller
@RequestMapping(value = Url.C_EMP)
public class EmpController extends SupporterController {
	private final static String upload_path = "upload/userAnnex/";

	private UserInfoDAO userDAO;
	private RoleDAO roleDAO;
	private OrganDAO organDAO;
	private FileDAO fDAO;
	private PostDAO pDAO;

	@RequestMapping(value = Url.INIT)
	public ModelAndView init(HttpServletRequest request, HttpServletResponse response) throws Exception {
		return new ModelAndView(Url.EMP_INIT);
	}

	@RequestMapping(value = Url.QUERY)
	public ModelAndView query(HttpServletRequest request, HttpServletResponse response) throws Exception {
		PageBean pb = createPageBean(request);
		Integer oc = cu_organCode(request);
		Map<String, String> map = createQueryMapByParmName(request, Parm.EMAIL, Parm.REAL_NAME, Parm.RC, Parm.DELETED, Parm.OC);
	/*	Integer cu_organCode = cu_organCode(request);
		
		if (cu_organCode != null) {
			String oc = request.getParameter(Parm.OC);
			Organ organ = null;
			if (isNotNull(oc))
				organ = organDAO.getOrgan(Integer.parseInt(oc));
			else
				organ = organDAO.getOrgan(cu_organCode);

			StringBuffer codes = new StringBuffer();
			organDAO.findSubCode(organ, codes);
			if (codes.length() > 0)
				codes.deleteCharAt(codes.length() - 1);
			map.put(Parm.OC, codes.toString());
			map.put(Parm.ORGAN_CODE, null);
		}
		*/
		if (userDAO.findByMap2(map, pb, organDAO.getSonCodeList(oc)) == RESULT.SUCCESS) {
			request.setAttribute(Parm.PAGE_BEAN, pb);
		}else {
			request.setAttribute(Parm.PAGE_BEAN, pb);
			print(response, Msg.NULL_OC);
		}
		return new ModelAndView(Url.EMP_LIST);
	}

	@RequestMapping(value = Url.EDIT)
	public ModelAndView edit(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String code = request.getParameter(Parm.CODE);
		Integer pc = organDAO.getRoot(cu_organCode(request)).getCode();
		request.setAttribute(Parm.PC, pc);
		if (isNotNull(code)) {
			UserInfo user = userDAO.get(Integer.parseInt(code));
			List<Role> roles = Cache.organRoleMap.get(organDAO.getRoot(cu_organCode(request)).getCode());		// 角色只跟根机构
			List<UserAnnex> list = userDAO.findUserAnnex(Integer.parseInt(code));
			user.setAnList(list);
			request.setAttribute(Parm.ROLES, roles);
			request.setAttribute(Parm.USER, user);
		}
		return new ModelAndView(Url.EMP_EDIT);
	}

	@RequestMapping(value = Url.SAVE_SELF)
	public ModelAndView saveSelf(UserInfo user, HttpServletRequest request, HttpServletResponse response) throws Exception {
		Integer cu_code = cu_code(request);
		
		if (null == cu_code) {
			request.setAttribute(Parm.INFO, Msg.NO_LOGIN);
			return new ModelAndView(Url.BS_LOGIN);
		}
		
		user.setCode(cu_code);
		
		if (userDAO.upd(user) == RESULT.SUCCESS) {
			// 加载当前机构的所有用户信息到缓存
			userDAO.loadUserList(cu_organCode(request));
			
			print(response, Msg.SUCCESS);
		} else 
			print(response, Msg.ERROR);
		
		return null;
	}
	@Transactional
	@RequestMapping(value = Url.SAVE)
	public void save(UserInfo user, HttpServletRequest request, HttpServletResponse response) throws Exception {
		RESULT result = RESULT.ERROR;
		
		// 验证  email 是否重复
		if (!userDAO.checkEmail(user.getEmail(),user.getCode())) {
			print(response, Msg.EXISTS);
			return;
		}
		Integer cu_organCode = cu_organCode(request);
		
		// 如果没有选择机构则默认是当前机构
		if (null == user.getOc()) {
			user.setOc(cu_organCode);
		}
		if (user.getRc() == null) {
			Role p = roleDAO.getDefaultRole(user.getOc());
			if (null != p)
				user.setRc(p.getCode());
		}
		if (isNotNull(user.getRealName())) {
			user.setPinyin(PinYinUtils.cn2py(user.getRealName()));
			user.setPy(PinYinUtils.cn2first(user.getRealName()));
		}
		//处理附件
		if (null != user.getCode())  {
			List<UserAnnex> deletedList = new ArrayList<UserAnnex>();	// 存放页面已经删除的附件
			List<UserAnnex> list = userDAO.findUserAnnex(user.getCode()); // 查询数据库有的附件
			Boolean ok = null;
			for (UserAnnex db : list) {
				ok = true;
				if (user.getAnList() == null || user.getAnList().size() == 0) {
					deletedList.add(db);
				} else {
					for (UserAnnex ua : user.getAnList()) {
						if (null != ua.getCode() && ua.getCode().intValue() == db.getCode().intValue()) {
							ok = false;
							break;
						} 
					}
					if (ok) {
						deletedList.add(db);
					}
				}
			}
			// 删除附件(在数据库中deleted = true)
			for (UserAnnex ua : deletedList) {
				ua.setDeleted(true);
				result = userDAO.upd(ua);
				if (RESULT.SUCCESS != result) {
					throw new Exception("保存失败"); 
				}
			}
			if (user.getAnList() != null && user.getAnList().size() > 0) {
				for (UserAnnex usera : user.getAnList()) {
					if (usera.getCode() == null &&isNotNull(usera.getName()) && isNotNull(usera.getUuid()) && isNotNull(usera.getExt()) && null != usera.getSize()) {
						usera.setUc(user.getCode());
						usera.setDeleted(false);
						userDAO.add(usera);
					}
				}
			}
			UserInfo old = userDAO.get(user.getCode());
			if(user.getRc() != null && user.getRc() != old.getRc()){
				Post p = new Post();
				p.setCt(new Date());
				p.setCu(cu_code(request));
				p.setDeleted(false);
				p.setOc(cu_organCode(request));
				p.setRc(user.getRc());
				p.setUc(user.getCode());
				pDAO.add(p);
			}
			result = userDAO.update(user);
			
		} else {
			user.setCt(new Date());
			user.setPwd(Sys.DEFAULT_PWD);
			result = userDAO.add(user);
			if (RESULT.SUCCESS == result) {
				if (null != user.getAnList() && user.getAnList().size() > 0) {
					for (UserAnnex ua : user.getAnList()) {
						if (isNotNull(ua.getName()) && isNotNull(ua.getUuid()) && isNotNull(ua.getExt()) && null != ua.getSize()) {
							ua.setUc(user.getCode());
							ua.setDeleted(false);
							result = userDAO.add(ua);
						}
					}
				}
			}
			if(user.getRc() != null){
				Post p = new Post();
				p.setCt(new Date());
				p.setCu(cu_code(request));
				p.setDeleted(false);
				p.setRc(user.getRc());
				p.setUc(user.getCode());
				p.setOc(user.getOc());
				pDAO.add(p);
			}
		}
		
		
		if (RESULT.SUCCESS == result) {
			// 加载当前机构的所有用户信息到缓存
			userDAO.loadUserList(cu_organCode);
			if (user.getRc() == null && (user.getIsManager() == null || !user.getIsManager()))
				print(response, Msg.NO_ANY_RIGHTS);
			else
				print(response, Msg.SUCCESS);
		} else 
			print(response, Msg.ERROR);
	}
	
	@RequestMapping(value = Url.DELETE)
	public void delete(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String code = request.getParameter(Parm.CODE);
		if (!isNotNull(code)) {
			print(response, Msg.PARAMETER_ERROR);
			return;
		}
		
		if (userDAO.del(Integer.parseInt(code)) == RESULT.SUCCESS) {
			// 加载当前机构的所有用户信息到缓存
			userDAO.loadUserList(cu_organCode(request));
			print(response, Msg.SUCCESS);
		} else 
			print(response, Msg.ERROR);
	}
	
	@RequestMapping(value = Url.SHIELD)
	public void shield(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String code = request.getParameter(Parm.CODE);
		if (!isNotNull(code)) {
			print(response, Msg.PARAMETER_ERROR);
			return;
		}
		UserInfo user = userDAO.get(Integer.parseInt(code));
		if (null == user) {
			print(response, Msg.NOT_FIND);
			return;
		}

		user.setDeleted(true);
		if (userDAO.upd(user) == RESULT.SUCCESS)
			print(response, Msg.SUCCESS);
		else
			print(response, Msg.ERROR);
	}
	
	@RequestMapping(value = Url.UN_SHIELD)
	public void unshield(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String code = request.getParameter(Parm.CODE);
		if (!isNotNull(code)) {
			print(response, Msg.PARAMETER_ERROR);
			return;
		}
		UserInfo user = userDAO.get(Integer.parseInt(code));
		if (null == user) {
			print(response, Msg.NOT_FIND);
			return;
		}
			
		user.setDeleted(false);
		if (userDAO.upd(user) == RESULT.SUCCESS)
			print(response, Msg.SUCCESS);
		else
			print(response, Msg.ERROR);
	}
	
	@RequestMapping(value = Url.UPDATE_PWD)
	public void updatePwd(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String oldpwd = request.getParameter("oldpwd");
		String newpwd = request.getParameter("newpwd");
		if (null == oldpwd || null == newpwd || newpwd.length() < 6) {
			print(response, Msg.PARAMETER_ERROR);
			return;
		}
		UserInfo user = userDAO.getByEmail(cu_email(request));
		if (null == user) {
			print(response, Msg.NOT_FIND);
			return;
		}
		if (!MD5Utils.encryptTo32(oldpwd).equals(user.getPwd())) {
			print(response, Msg.PWD_ERROR);
			return;
		}
		user.setPwd(MD5Utils.encryptTo32(newpwd));
		if (userDAO.upd(user) == RESULT.SUCCESS)
			print(response, Msg.SUCCESS);
		else 
			print(response, Msg.ERROR);
	}

	@RequestMapping(value = Url.VALIDATE_EMAIL_EXIST)
	public void validateLoginEmailExist(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String email = request.getParameter(Parm.EMAIL);
		if (!isNotNull(email)) {
			print(response, Msg.PARAMETER_ERROR);
			return;
		}
		
		UserInfo user = userDAO.getByEmail(email);
		if (null != user) {
			print(response, Msg.EXISTS);
		} else {
			print(response, Msg.NOT_FIND);
		}
	}
	
	@RequestMapping(value = Url.UPDATE_PAGE_STYLE)
	public void updatePageStyle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String pageStyle = request.getParameter(Parm.PAGE_STYLE);
		
		if (null == pageStyle || Sys.NONE.equals(pageStyle)) {
			print(response, Msg.PARAMETER_ERROR);
			return;
		}
		
		UserInfo user = userDAO.get(cu_code(request));
		if (null == user) {
			print(response, Msg.NOT_FIND);
			return;
		}
		
		user.setPageStyle(pageStyle);
		if (userDAO.upd(user) == RESULT.SUCCESS) {
			request.getSession().setAttribute(Parm.CU_PAGE_STYLE, pageStyle);
			print(response, Msg.SUCCESS);
		} else {
			print(response, Msg.FAILURE);
		}
	}
	
	@RequestMapping(Url.AID_INIT)
	public ModelAndView aidInit(HttpServletRequest request, HttpServletResponse response) throws Exception {
		request.setAttribute(Parm.OC, request.getParameter(Parm.OC));
		request.setAttribute(Parm.ON, request.getParameter(Parm.ON));

		Integer code = cu_organCode(request);
		if (null != code) {
			List<Organ> list = organDAO.getAll();
			Organ o = findOgranByCode(code, list);
			if (null != o) {
				StringBuffer tree = new StringBuffer();
				if (!o.getDeleted()) {
					tree.append("p.add('" + o.getCode() + "','-1','" + o.getName() + "');");
					aidTree(tree, o.getSonList());
				}
				request.setAttribute(Parm.TREE, tree);
				request.setAttribute(Parm.ORGAN, o);
			}
		}
		return new ModelAndView(Url.EMP_AID_INIT);
	}
	
	private Organ findOgranByCode(Integer code, List<Organ> list){
		if(null != code && null != list && 0 < list.size()){
			for (Organ o : list){
				if(code.intValue() == o.getCode().intValue()){
					return o;
				} else {
					Organ or = findOgranByCode(code, o.getSonList());
					if (or != null) {
						return or;
					}
				}
			}
		}
		return null;
	}
	
	private void aidTree(StringBuffer tree, List<Organ> list) {
		if (null == tree || null == list || list.size() == 0)
			return;
		for (Organ o : list) {
			tree.append("p.add('" + o.getCode() + "','" + o.getPc() + "','" + o.getName() + "');");
			aidTree(tree, o.getSonList());
		}
	}

	/** 下面几个方法是辅助其他模块查询用户时使用 */
	@RequestMapping(value = Url.AID_INIT_1)
	public ModelAndView aidInit1(HttpServletRequest request, HttpServletResponse response) throws Exception {
		request.setAttribute(Parm.ID, request.getParameter(Parm.ID));
		request.setAttribute(Parm.NAME, request.getParameter(Parm.NAME));
		return new ModelAndView(Url.EMP_QUERY_INIT);
	}
	
	@RequestMapping(value = Url.AID_LIST_1)
	public ModelAndView aidList1(HttpServletRequest request, HttpServletResponse response) throws Exception {
		PageBean pb = createPageBean(request);
		Map<String, String> map = createQueryMapByParmName(request, Parm.EMAIL, Parm.REAL_NAME, Parm.ROLE_CODE, Parm.DELETED);
		
		if (userDAO.findByMap(map, pb) == RESULT.SUCCESS)
			request.setAttribute(Parm.PAGE_BEAN, pb);
		return new ModelAndView(Url.EMP_QUERY_LIST);
	}
	
	@RequestMapping(Url.CHANGE_ROLE)
	public void changeRole(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String strOc = request.getParameter(Parm.OC);
		response.setContentType("application/json;charset=utf-8");
		Gson gson = new Gson();
		String json = gson.toJson(roleDAO.getAllByOrgCode(strOc));
		response.getWriter().write(json);
	}
	
	/**
	 * 上传多张图片和多个文件
	 */
	@Transactional
	@RequestMapping(Url.UPLOADS)
	public void uploads(Integer code, HttpServletRequest request, HttpServletResponse response) {
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		List<MultipartFile> files = multipartRequest.getFiles("files");

		StringBuffer result = new StringBuffer("");
		if (null != files && files.size() > 0) {

			String name = null;
			String ext = null;
			String uuid = null;
			String path = null;
			String savePath = null;
			UUID u = null;

			for (MultipartFile mf : files) {
				name = mf.getOriginalFilename();
				//System.out.println(mf.getOriginalFilename() + "--" + mf.getName());
				if (isNotNull(name)) {
					ext = name.substring(name.lastIndexOf('.') + 1);
					if (!ext.toUpperCase().equals(Sys.JPG)
							&& !ext.toUpperCase().equals(Sys.GIF)
							&& !ext.toUpperCase().equals(Sys.JPEG)
							&& !ext.toUpperCase().equals(Sys.BMP)
							&& !ext.toUpperCase().equals(Sys.PNG)
							&& !ext.toUpperCase().equals(Sys.XLSX)
							&& !ext.toUpperCase().equals(Sys.XLS)
							&& !ext.toUpperCase().equals(Sys.DOCX)
							&& !ext.toUpperCase().equals(Sys.DOC)
							&& !ext.toUpperCase().equals(Sys.PDF)
							&& !ext.toUpperCase().equals(Sys.PPT)
							&& !ext.toUpperCase().equals(Sys.RAR)
							&& !ext.toUpperCase().equals(Sys.ZIP)) {
						print(response, Msg.J_FILE_TYPE_ERROR);
						return;
					}
					name = name.substring(0, name.lastIndexOf('.'));

					u = UUID.randomUUID();
					uuid = u.toString().replace("-", "");
					path = upload_path + uuid + Sys.DOT + ext;
					savePath = ConfigParm.getProjectPath() + path;
					FileOutputStream fo;
					int size = 0;
					
				
					try {
						fo = new FileOutputStream(savePath);
						size = mf.getBytes().length;
						fo.write(mf.getBytes());
						fo.close();
					} catch (Exception e) {
						print(response, Msg.ERROR);
						e.printStackTrace();
					}

					FileInfo f = new FileInfo();
					f.setDeleted(false);
					f.setExt(ext);
					f.setName(name);
					f.setCt(new Date());
					f.setType(isImg(ext) ? Sys.B_TWO : Sys.B_ONE);
					f.setModule(Parm.USER_ANNEX);
					f.setCu(cu_code(request));
					f.setOc(cu_organCode(request));
					f.setSize(size);
					userDAO.add(f);

					result.append("{\"name\":\"" + name + "\",\"uuid\":\"" + uuid + "\",\"ext\":\"" + ext + "\",\"size\":\"" + size + "\",\"path\":\"" + uuid + Sys.DOT + ext + "\"},");
				}
			}

			result.insert(0, "{\"result\":\"success\",\"list\":[").deleteCharAt(result.length() - 1).append("]}");
			print(response, result.toString());
		} else {
			result.append("{\"result\":\"not_find_file\"}");
		}
	}
	
	private boolean isImg(String ext) {
		if (!isNotNull(ext))
			return false;
		if (ext.toUpperCase().equals(Sys.JPG)
				|| ext.toUpperCase().equals(Sys.GIF)
				|| ext.toUpperCase().equals(Sys.JPEG)
				|| ext.toUpperCase().equals(Sys.BMP)
				|| ext.toUpperCase().equals(Sys.PNG)) {
			return true;
		}
		return false;
	}
	@Transactional
	@RequestMapping(value = Url.DOWNLOAD)
	public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String code = request.getParameter(Parm.CODE);
		if (!isNotNull(code)) {
			print(response, Msg.PARAMETER_ERROR);
			return;
		}
		FileInfo fi = fDAO.getByUuid(code);
		
		if (null == fi) {
			print(response, Msg.ERROR);
			return;
		}
		DownLoadUtils.downLoad(upload_path, fi.getName(), fi.getUuid(), fi.getExt(), response);
	}
	@Autowired
	public void setUserDAO(UserInfoDAO userDAO) {
		this.userDAO = userDAO;
	}
	@Autowired
	public void setRoleDAO(RoleDAO roleDAO) {
		this.roleDAO = roleDAO;
	}
	@Autowired
	public void setOrganDAO(OrganDAO organDAO) {
		this.organDAO = organDAO;
	}
	@Autowired
	public void setfDAO(FileDAO fDAO) {
		this.fDAO = fDAO;
	}
	@Autowired
	public void setpDAO(PostDAO pDAO) {
		this.pDAO = pDAO;
	}
}
